from datetime import datetime
import os
import re
import shutil
import time

from flask_sqlalchemy import SQLAlchemy
from plantuml import PlantUML

# 定义第三方插件对象，防止循环引用

db = SQLAlchemy(session_options={"autoflush": False})

# 或者使用本地 PlantUML JAR 文件
# puml = PlantUML(jar_path='/jar/plantuml-1.2024.8.jar')
plant_uml = PlantUML(url='http://www.plantuml.com/plantuml/img/')
plant_uml_local = PlantUML(url='http://localhost:8090/png/')

def run_plant_uml():
    output_file = 'uml_8090.png'
    output_file2 = 'uml_8090_2.png'
    puml_code = """
    @startuml
    skinparam ArrowColor black  // 设置连线颜色为黑色
    skinparam ArrowThickness 2  // 设置连线粗细
    
    left to right direction
        title Demo功能2
        [GSM]-up-> [TCU]
        [EMS]-> [TCU]
        [EMS]-[#blue]-> [TCU]
        [TCU] ---- [GW]
        [GW] ...> [IP]
    @enduml    
    """
    # 记录开始时间
    start_time = time.time()
    # 生成图并保存为文件
    image = plant_uml_local.processes(puml_code)
    # 记录结束时间
    end_time = time.time()
    # 计算执行时间
    execution_time = end_time - start_time
    print(f"plant_uml_local执行时间: {execution_time:.6f} 秒")

    # 记录开始时间
    start_time = time.time()
    # 生成图并保存为文件
    image2 = plant_uml.processes(puml_code)
    # 记录结束时间
    end_time = time.time()
    # 计算执行时间
    execution_time = end_time - start_time
    print(f"plant_uml行时间: {execution_time:.6f} 秒")
    with open(output_file, "wb") as file:
        file.write(image)
    with open(output_file2, "wb") as file:
        file.write(image2)

def create_uml_picture(uml_code, title, item_id, pid):

    uml_path = f'static/plantuml/{pid}'
    uml_file_name = f'item_{item_id}_uml.png'
    target_file = os.path.join(uml_path, uml_file_name)
    if os.path.exists(target_file):
        # os.remove(target_file)
        return

    print(f'create_uml_picture: {target_file}, {uml_code}, {title}')
    plant_uml_code = f"""
        @startuml
            skinparam componentStyle rectangle
            title {title}
            Rectangle {{
            
            {uml_code}
            
            }}
        
        @enduml
    """
    # 生成图并保存为文件
    try:
        image = plant_uml.processes(plant_uml_code)
        with open(target_file, "wb") as file:
            file.write(image)
        print(f'create_uml_picture: OK')
    except Exception as e:
        print(e)


def update_uml_picture(uml_code, title, item_id, pid):
    uml_path = f'static/plantuml/{pid}'
    uml_file_name = f'item_{item_id}_uml.png'
    target_file = os.path.join(uml_path, uml_file_name)
    if os.path.exists(target_file):
        os.remove(target_file)

    print(f'create_uml_picture: {target_file}, {uml_code}, {title}')
    plant_uml_code = f"""
        @startuml
            skinparam componentStyle rectangle
            title {title}
            Rectangle {{

            {uml_code}

            }}

        @enduml
    """
    # 生成图并保存为文件
    try:
        image = plant_uml.processes(plant_uml_code)
        with open(target_file, "wb") as file:
            file.write(image)
        print(f'create_uml_picture: OK')
    except Exception as e:
        print(f'create_uml_picture: Error {e}')
"""
@startuml
skinparam componentStyle rectangle
title xxx
Rectangle {
    component 遥控钥匙
    component IBCM
    component 门锁
    component 四门状态

    遥控钥匙 -right-> IBCM : 控制信号
    IBCM -down-> 门锁 : 控制信号
    四门状态 -left-> IBCM : 状态反馈
}

@enduml
"""

def generate_plantuml_code(input_info):
    if None == input_info:
        return
    # 将输入信息按逗号分隔成多个连接部分
    connections = re.split(r'[;\n]', input_info)

    # 用于存储唯一的连接部分
    unique_connections = set()

    # 遍历每个连接部分
    for connection in connections:
        # 去除前后空格
        connection = connection.strip()
        # 将连接部分按“—>”分隔成组件
        parts = re.split(r'—>', connection)
        # 如果连接部分不包含“—>”，则跳过
        if len(parts) < 2:
            continue
        # 遍历组件关系，生成PlantUML代码
        for i in range(len(parts) - 1):
            # 处理起始组件，可能有多个
            src_part = parts[i].strip()
            src_components = re.split(r'[，、& /]', src_part.strip('<'))
            # dst_component = parts[i+1].strip()
            # 处理后续组件，可能有多个
            dst_part = parts[i+1].strip()
            dst_components = re.split(r'[，、& /]', dst_part.strip('>'))

            # 生成连接代码
            for src in src_components:
                src = src.strip()
                for dst in dst_components:
                    dst = dst.strip()
                    unique_connections.add(f"[{src}]-->[{dst}]:")

    # 将唯一的连接部分排序并连接成最终的代码
    plantuml_code = "\n".join(sorted(unique_connections))

    return plantuml_code

def backup_database():
    try:
        # 复制数据库文件到备份目录
        shutil.copy2('database/data.db', f'database/data.db_{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}.bak')
        return f'Database backup successful', 200
    except Exception as e:
        return f'Database backup failed: {str(e)}', 500